package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.format.FastDateFormat;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Lists;
import com.zhijian.medical.dao.local.DeviceMapper;
import com.zhijian.medical.dao.remote.MedicalDeviceMapper;
import com.zhijian.medical.entity.po.Device;
import com.zhijian.medical.entity.po.MedicalDevice;
import com.zhijian.medical.entity.vo.request.DeviceMaintenanceRecordSearchVo;
import com.zhijian.medical.entity.vo.request.DeviceSaveOrUpdateVo;
import com.zhijian.medical.entity.vo.request.DeviceSearchVo;
import com.zhijian.medical.entity.vo.response.DeviceMaintenanceRecordVo;
import com.zhijian.medical.entity.vo.response.DeviceVo;
import com.zhijian.medical.enums.DeviceStatusEnum;
import com.zhijian.medical.service.DeviceMaintenanceRecordService;
import com.zhijian.medical.service.DeviceService;
import com.zhijian.medical.util.AssertUtil;
import com.zhijian.medical.util.JsonUtil;
import com.zhijian.medical.util.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 医疗设备业务处理层
 *
 * @author HCG
 * @date 2022-01-01 15:37:21
 * @version: 1.0
 */
@Slf4j
@Service
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private DeviceMapper mapper;

    @Autowired
    private MedicalDeviceMapper medicalDeviceMapper;

    @Autowired
    private DeviceMaintenanceRecordService deviceMaintenanceRecordService;

    @Override
    public Device selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public DeviceVo selectVoById(Long id) {
        DeviceVo deviceVo = mapper.selectVoById(id);
        if (ObjectUtil.isNull(deviceVo)) {
            return null;
        }
        String supervisionContent = deviceVo.getSupervisionContent();
        if (StringUtils.isNotBlank(supervisionContent)) {
            deviceVo.setSupervisionContentList(JsonUtil.toArray(supervisionContent, DeviceSaveOrUpdateVo.SupervisionContentVo.class));
        }
        return deviceVo;
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public Long insert(Device device) {
        Date now = new Date();
        device.setCreateTime(now);
        device.setUpdateTime(now);
        return mapper.insert(device) == 1 ? device.getId() : 0L;
    }

    @Override
    public boolean save(DeviceSaveOrUpdateVo deviceSaveOrUpdateVo) {
        Device device = new Device();
        BeanUtils.copyProperties(deviceSaveOrUpdateVo, device);
        if (CollectionUtil.isNotEmpty(deviceSaveOrUpdateVo.getSupervisionContentList())) {
            device.setSupervisionContent(JsonUtil.toString(deviceSaveOrUpdateVo.getSupervisionContentList()));
        }
        return this.insert(device) != 0;
    }

    @Override
    public boolean modify(DeviceSaveOrUpdateVo deviceSaveOrUpdateVo) {
        Device device = new Device();
        BeanUtils.copyProperties(deviceSaveOrUpdateVo, device);
        if (CollectionUtil.isNotEmpty(deviceSaveOrUpdateVo.getSupervisionContentList())) {
            device.setSupervisionContent(JsonUtil.toString(deviceSaveOrUpdateVo.getSupervisionContentList()));
        }
        return this.update(device);
    }

    @Override
    public boolean update(Device device) {
        Date now = new Date();
        device.setUpdateTime(now);
        return mapper.updateByPrimaryKey(device) != 0;
    }

    @Override
    public boolean updateByPrimaryKeySelective(Device record) {
        record.setUpdateTime(new Date());
        return mapper.updateByPrimaryKeySelective(record) != 0;
    }

    @Override
    public boolean updateStatus(Long id, String status) {
        Device device = this.selectById(id);
        AssertUtil.notNull(device, "此设备不存在或者已被删除");
        DeviceStatusEnum deviceStatusEnum = DeviceStatusEnum.getByAlias(status);
        AssertUtil.notNull(deviceStatusEnum, "设备状态非法");
        return this.updateByPrimaryKeySelective(Device.builder()
                .id(id)
                .status(status)
                .build());
    }

    @Override
    public Integer count(DeviceSearchVo deviceSearchVo) {
        return mapper.count(deviceSearchVo);
    }

    @Override
    public List<DeviceVo> selectList(DeviceSearchVo deviceSearchVo) {
        List<DeviceVo> deviceVos = mapper.selectList(deviceSearchVo);
        if (CollectionUtil.isEmpty(deviceVos)) {
            return Collections.emptyList();
        }
        for (DeviceVo deviceVo : deviceVos) {
            String supervisionContent = deviceVo.getSupervisionContent();
            if (StringUtils.isNotBlank(supervisionContent)) {
                deviceVo.setSupervisionContentList(JsonUtil.toArray(supervisionContent, DeviceSaveOrUpdateVo.SupervisionContentVo.class));
            }
        }
        return deviceVos;
    }

    @Override
    public List<DeviceVo> selectListWithMaintenance(DeviceSearchVo deviceSearchVo) {
        List<DeviceVo> deviceVos = this.selectList(deviceSearchVo);
        if (CollectionUtil.isEmpty(deviceVos)) {
            return Collections.emptyList();
        }
        for (DeviceVo deviceVo : deviceVos) {
            //搜保养表
            List<DeviceMaintenanceRecordVo> deviceMaintenanceRecordVos = deviceMaintenanceRecordService.selectList(DeviceMaintenanceRecordSearchVo.builder()
                    .deviceId(deviceVo.getId())
                    .build());
            List<DeviceVo.MaintenanceDateVo> maintenanceDateVoList = Lists.newArrayList();
            if (CollectionUtil.isNotEmpty(deviceMaintenanceRecordVos)) {
                //组装保养记录
                for (DeviceMaintenanceRecordVo deviceMaintenanceRecordVo : deviceMaintenanceRecordVos) {
                    DeviceVo.MaintenanceDateVo maintenanceDateVo = new DeviceVo.MaintenanceDateVo();
                    maintenanceDateVo.setWeek(deviceMaintenanceRecordVo.getWeek());
                    maintenanceDateVo.setMonth(deviceMaintenanceRecordVo.getMonth());
                    maintenanceDateVoList.add(maintenanceDateVo);
                }
            }
            deviceVo.setMaintenanceDateList(maintenanceDateVoList);
        }
        return deviceVos;
    }

    @Override
    public Page<DeviceVo> selectPage(DeviceSearchVo deviceSearchVo) {
        //todo
//        if (!CollectionUtils.isEmpty(deviceSearchVo.getGroupIds())) {
//            //如果查询条件有部门id集合，挨个查出他们所有的子级部门，拼接查询所有的部门id
//            List<Long> groupIds = new LinkedList<>();
//            deviceSearchVo.getGroupIds().forEach(groupId -> {
//                List<Long> newGroupIds = officeGroupService.concatIdsByParentId(groupId);
//                groupIds.addAll(newGroupIds);
//            });
//            deviceSearchVo.setGroupIds(groupIds);
//        } else {
//            deviceSearchVo.setGroupIds(Collections.singletonList(0L));
//        }
        //先直接查总数
        int count = count(deviceSearchVo);
        //分页
        Page<DeviceVo> page = new Page<>(true, count, deviceSearchVo.getPageNum(), deviceSearchVo.getPageSize());
        deviceSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<DeviceVo> responseVos = this.selectList(deviceSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public List<Device> selectListByType(String type) {
        return mapper.selectListByType(type);
    }

    @Override
    public List<Device> selectListByExperimentProcessId(Long experimentProcessId) {
        return mapper.selectListByExperimentProcessId(experimentProcessId);
    }

    @Override
    public List<MedicalDevice> selectRfidList() {
        return medicalDeviceMapper.selectRfidList();
    }

    public static final String CODE_PREFIX = "BLK-PF-019-003";

    @Override
    public String selectMaxCode() {
        return mapper.selectMaxCodeByDay(DateUtil.formatDate(new Date()));
    }

    @Override
    public String createNextCode() {
        String maxCode = this.selectMaxCode();
        if (StringUtils.isBlank(maxCode)) {
            return String.format("%s-%s-1", CODE_PREFIX, DateUtil.format(new Date(), FastDateFormat.getInstance("yyyyMMdd")));
        }
        String[] maxCodeArray = maxCode.split("-");
        Integer i = Integer.valueOf(maxCodeArray[maxCodeArray.length - 1]);
        i++;
        return String.format("%s-%s-%s", CODE_PREFIX, DateUtil.format(new Date(), FastDateFormat.getInstance("yyyyMMdd")), i);
    }
}